///////////////////////////////////////////////////////////////////////////////
//版权所有（C）2002-2022，成都梦想凯德科技有限公司。
//本软件代码及其文档和相关资料归成都梦想凯德科技有限公司
//应用包含本软件的程序必须包括以下声明
//在版权声明中：
//此应用程序与成都梦想凯德科技有限公司成协议。
//通过使用本软件、其文档或相关材料
//http://www.mapbox.cn/mapbox-gl-js/api/#lnglatboundslike
//http://www.mapbox.cn/mapbox-gl-js/api/#scrollzoomhandler
//http://www.mapbox.cn/mapbox-gl-js/api/#boxzoomhandler
//http://www.mapbox.cn/mapbox-gl-js/api/#dragrotatehandler
//http://www.mapbox.cn/mapbox-gl-js/api/#dragpanhandler
//http://www.mapbox.cn/mapbox-gl-js/api/#keyboardhandler
//http://www.mapbox.cn/mapbox-gl-js/api/#doubleclickzoomhandler
//http://www.mapbox.cn/mapbox-gl-js/api/#map#fitbounds


///////////////////////////////////////////////////////////////////////////////

import mapboxgl from "mapbox-gl";
import "mapbox-gl/dist/mapbox-gl.css";
import { init as mxDrawInit, MxMap } from "./mxdrawInit";
import { Map } from "./Map";

// export let map: Map
let map: Map;
let mxMap: MxMap;

const mapOrigin = [116.391305, 39.90553];

export namespace MxMapBox {

  export function getMap() {
    return map;
  }

  export async function init(param: any) {

    //  图纸中的中心在地址上的位置，单位经纬度
    let ptMapOrigin = param.mapOrigin ? param.mapOrigin : mapOrigin;

    //  CAD图纸中的中心中，CAD图纸单位
    let ptCADOrigin = param.cadOrigin ? param.cadOrigin : [0, 0];

    // 一个CAD绘图单位，是现实中多少米.
    let meterInCADUnits = param.meterInCADUnits ? param.meterInCADUnits : 1;

    let zoom = param.zoom ? param.zoom : 16;

    let mapParam = param.mapparam;

    if (!mapParam) {

      mapParam = {
        container: "map", //Mapbox GL JS 进行地图渲染的 HTML 元素，或该元素的字符串 id 。该指定元素不能有子元素。
        minZoom: 0,// 地图最小缩放级别（0-24）。
        maxZoom: 24,// 地图最大缩放级别（0-24）。
        style: { version: 8, sources: {}, glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", layers: [] } as mapboxgl.Style,// 地图的 Mapbox 配置样式
        hash: false,// 如果为 true ，地图的位置 (包括缩放层级、中心纬度、中心经度、方位角和倾角) 将会与页面URL的哈希片段同步
        interactive: true, // 如果为 false ，地图将不会绑定对鼠标、触碰、键盘的监听，因此地图将不会响应任何用户交互
        bearingSnap: 7,// 定义何时地图的方位将自动对齐到正北方向的阈值（以度为单位）
        pitchWithRotate: true, // 如果为 false ，将不会在"拖拽进行地图旋转"的同时控制地图的倾斜。
        clickTolerance: 3, // 当用户点击地图时能进行鼠标移动的最大像素范围，点击地图后鼠标在此像素范围内移动则被认为是一次有效的点击(而不是拖拽)。
        attributionControl: true,// 如果为 true ， AttributionControl(一个 AttributionControl 控制展示地图的属性信息
        customAttribution: [], // 在 attributionControl 中显示的字符串或字符串数组。仅当 options.attributionControl 为 true 时生效。
        logoPosition: "bottom-left",// 设置 Mapbox 文字商标在地图上的位置。可选填以下值 top-left ， top-right ， bottom-left ， bottom-right 。
        failIfMajorPerformanceCaveat: false, // 如果为 true ， 当 Mapbox GL JS 的性能远远低于预期的时候，地图将创建失败。 (换句话说，此时可能是用的软件渲染器)。
        preserveDrawingBuffer: false, // 如果为 true ，地图画布可通过 map.getCanvas().toDataURL() 输出 PNG 。出于性能优化考虑，该值默认为 false 。
        antialias: false,// 如果为 true ，gl 渲染环境在创建时将开启多重采样抗锯齿模式（ MSAA ）, 这对自定义图层的抗锯齿十分有效。出于性能优化考虑，该值默认为 false 。
        refreshExpiredTiles: true, // 如果为 false ，一旦切片的 HTTP cacheControl / expires headers 过期，地图将不会重新请求这些切片。
        maxBounds: void 0,// 设置一个LngLatBounds对象，或者是一个LngLatLike对象的数组以[西南，东北]为顺序， 也可以是一个数字组成的数组以[西，南，东，北]为顺序。 设置之后，地图将限制在给定的最大范围内。
        scrollZoom: true,// 如果为 true ，将开启 "滚轮缩放地图" 交互模式。如果传值为 Object 对象，对象可选参数参考  enable
        boxZoom: true,// 如果为 true , 将开启 "框选缩放地图" 交互模式
        dragRotate: true,// 如果为 true , 将开启 "拖拽旋转地图" 交互模式
        dragPan: true,// 如果为 true , 将开启 "拖拽移动地图" 交互模式
        keyboard: true, // 如果为 true ，将启用键盘快捷键功能
        doubleClickZoom: true,// 如果为 true ，将开启 "双击缩放地图" 交互模式
        touchZoomRotate: true,// 如果为 true ，将开启 "捏合旋转、缩放" 交互模式。
        trackResize: true, // 如果为 true ，地图将自适应窗口大小变化。
        center: ptMapOrigin,// 地图初始化时的地理中心点。如果构造函数的参数中没有设置 center ，Mapbox GL JS 会在地图样式中进行查找。如果样式中也没定义的话，那么它将默认为 [0, 0] 注意: 为了与 GeoJSON 保持一致，Mapbox GL 采用经度，纬度的顺序 (而不是纬度，经度)。
        zoom: zoom,// 地图初始化时的层级。如果构造函数的参数中没有设置 zoom Mapbox GL JS 会在地图样式中进行查找。如果样式中也没定义的话，那么它将默认为 0
        bearing: 0, // 地图初始化时的方位角（旋转角度），以正北方的逆时针转动度数计量
        pitch: 0, // 地图初始化时的倾角，按偏离屏幕水平面的度数计量（0-60）
        bounds: void 0, // 设置一个LngLatBounds对象 地图初始化时的限制范围。如果设置了 bounds 将会覆盖掉 center 和 zoom 在构造函数中的参数设置
        fitBoundsOptions: void 0, // fitBounds 仅用于 初始化地图时自适应设置的 bounds 范围时的情况。
        renderWorldCopies: true, // 如果为 true ，地图缩小时将渲染多个全局地图的副本。
        maxTileCacheSize: void 0, // 设置当前数据源存储在切片缓存中的最大切片数目。如果不设置，将基于当前视角动态计算切片缓存大小。
        // 定义一个用于在本地替代通用‘中日韩越统一表意文字’，’平假名’，‘片假名’和‘朝鲜文音节’字形的 CSS 字体系列。 在上述字体在地图样式中的设置，除字体粗细（light/regular/medium/bold）外，都将被忽略。 当设置为 false ，上述字体则使用地图样式中的设置。 该参数的目的是为了避免超带宽的字形请求 https://docs.mapbox.com/mapbox-gl-js/example/local-ideographs/
        localIdeographFontFamily: "sans-serif",
        // 地图发送外部 URL 请求前执行的回调函数。回调函数中可修改 URL 、设置请求头或设置跨源请求的相关身份凭证。回调返回的对象参数包含 url 属性和可选的 headers 以及 credentials 属性。
        transformRequest: void 0,
        // 如果为 true ，那么将为 GeoJSON 和 Vector Tile web workers 发出的请求搜集资源耗时API信息（通常无法从 Javascript 主线程中访问此信息）。该信息将在 resourceTiming 属性中返回（对应于 data 事件）
        collectResourceTiming: false,
        // 控制标注冲突时，淡入淡出的动画过渡时间, 单位为毫秒。该设置将应用于所有 symbol 图层。对于运行时的样式变化和栅格切片的淡入淡出，此设置不生效。
        fadeDuration: 300,
        // 如果为 true ，来自不同数据源的符号将共同参与到碰撞检测中。如果为 false ，仅在各自的数据源中相互独立的进行符号的碰撞检测。
        crossSourceCollisions: true,
        // 设置之后，地图将用此 token 替换掉在 mapboxgl.accessToken 中设置的值。
        accessToken: ' ',
      };
    }

    map = new Map(mapParam);

    // 监听地图样式加载
    map.on("style.load", async () => {
      // 加载用于图层分隔的空图层 (层级优先: 点 > 线 > 面 )
      map.addGroupLayer();
      let cadFile: string = param.cadFile;
      if (!cadFile) {
        cadFile = "empty.dwg";
      }

      // 初始化图纸显示
      mxMap = await mxDrawInit(map, ptMapOrigin, ptCADOrigin, meterInCADUnits, cadFile);

      if (param.call) {
        param.call(map, mxMap);
      }
    });
  }
}
